////
//// BuildScript.cs
////
//// Author:
////       fjy <jiyuan.feng@live.com>
////
//// Copyright (c) 2020 fjy
////
//// Permission is hereby granted, free of charge, to any person obtaining a copy
//// of this software and associated documentation files (the "Software"), to deal
//// in the Software without restriction, including without limitation the rights
//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//// copies of the Software, and to permit persons to whom the Software is
//// furnished to do so, subject to the following conditions:
////
//// The above copyright notice and this permission notice shall be included in
//// all copies or substantial portions of the Software.
////
//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//// THE SOFTWARE.

//using System;
//using System.Collections.Generic;
//using System.IO;
//using UnityEditor;
//using UnityEngine;

//namespace libx
//{
//    public static class BuildScript
//    {
//        public static void ClearAssetBundles()
//        {
//            var allAssetBundleNames = AssetDatabase.GetAllAssetBundleNames();
//            for (var i = 0; i < allAssetBundleNames.Length; i++)
//            {
//                var text = allAssetBundleNames[i];
//                if (EditorUtility.DisplayCancelableProgressBar(
//                    string.Format("Clear AssetBundles {0}/{1}", i, allAssetBundleNames.Length), text,
//                    i * 1f / allAssetBundleNames.Length))
//                    break;

//                AssetDatabase.RemoveAssetBundleName(text, true);
//            }

//            EditorUtility.ClearProgressBar();
//        }

//        internal static void ApplyBuildRules()
//        {
//            //var rules = GetBuildRules();
//            //rules.Apply();
//        }

//        internal static BundleRules GetBuildRules()
//        {
//            return GetAsset<BundleRules>("Assets/BundleRules.asset");
//        }

//        public static void CopyAssetBundlesTo(string copyToDirPath)
//        {
//            if (!Directory.Exists(copyToDirPath))
//            {
//                Directory.CreateDirectory(copyToDirPath);
//            }

//            var source = Path.Combine(Environment.CurrentDirectory, Assets.AssetBundles);
//            if (!Directory.Exists(source))
//            {
//                Debug.LogError($"assetBundle folder not exist: {source}, try to build the assetBundles first.");
//                return;
//            }

//            var destination = Path.Combine(copyToDirPath, Assets.AssetBundles);
//            if (Directory.Exists(destination))
//                FileUtil.DeleteFileOrDirectory(destination);

//            FileUtil.CopyFileOrDirectory(source, destination); //src文件夹内的所有文件copy到dst文件夹
//        }

//        public static string GetPlatformName()
//        {
//            return GetPlatformForAssetBundles(EditorUserBuildSettings.activeBuildTarget);
//        }

//        private static string GetPlatformForAssetBundles(BuildTarget target)
//        {
//            // ReSharper disable once SwitchStatementMissingSomeCases
//            switch (target)
//            {
//                case BuildTarget.Android:
//                    return "Android";
//                case BuildTarget.iOS:
//                    return "iOS";
//                case BuildTarget.WebGL:
//                    return "WebGL";
//                case BuildTarget.StandaloneWindows:
//                case BuildTarget.StandaloneWindows64:
//                    return "Windows";
//#if UNITY_2017_3_OR_NEWER
//                case BuildTarget.StandaloneOSX:
//                    return "OSX";
//#else
//                case BuildTarget.StandaloneOSXIntel:
//                case BuildTarget.StandaloneOSXIntel64:
//                case BuildTarget.StandaloneOSXUniversal:
//                    return "OSX";
//#endif
//                default:
//                    return null;
//            }
//        }

//        private static string[] GetLevelsFromBuildSettings()
//        {
//            List<string> scenes = new List<string>();
//            foreach (UnityEngine.Object item in GetBuildRules().scenes)
//            {
//                var path = AssetDatabase.GetAssetPath(item);
//                if (!string.IsNullOrEmpty(path))
//                {
//                    Debug.Log($"build scene path: {path}");
//                    scenes.Add(path);
//                }
//            }

//            return scenes.ToArray();
//        }

//        private static string GetAssetBundleManifestFilePath()
//        {
//            var relativeAssetBundlesOutputPathForPlatform = Path.Combine(Assets.AssetBundles, GetPlatformName());
//            return Path.Combine(relativeAssetBundlesOutputPathForPlatform, GetPlatformName()) + ".manifest";
//        }

//        public static void BuildStandalonePlayer()
//        {
//            // var outputPath = EditorUtility.SaveFolderPanel("Choose Location of the Built Game", "", "");
//            //比如: Assets/Build/windows/
//            var outputPath = Path.Combine(Environment.CurrentDirectory, "Build", GetPlatformName().ToLower()); 
//            if (outputPath.Length == 0)
//                return;

//            var levels = GetLevelsFromBuildSettings();
//            if (levels.Length == 0)
//            {
//                Debug.LogError("Nothing to build.");
//                return;
//            }

//            var targetName = GetBuildTargetName(EditorUserBuildSettings.activeBuildTarget);
//            if (targetName == null)
//                return;

//#if UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0
//			BuildOptions option = EditorUserBuildSettings.development ? BuildOptions.Development : BuildOptions.None;
//			BuildPipeline.BuildPlayer(levels, outputPath + targetName, EditorUserBuildSettings.activeBuildTarget, option);
//#else
//            var buildPlayerOptions = new BuildPlayerOptions
//            {
//                scenes = levels,
//                locationPathName = outputPath + targetName,
//                assetBundleManifestPath = GetAssetBundleManifestFilePath(),
//                target = EditorUserBuildSettings.activeBuildTarget,
//                options = EditorUserBuildSettings.development ? BuildOptions.Development : BuildOptions.None
//            };
//            BuildPipeline.BuildPlayer(buildPlayerOptions);
//#endif
//        }

//        public static string CreateAssetBundleDirectory()
//        {
//            // Choose the output path according to the build target.
//            var outputPath = Path.Combine("Output", GetPlatformName()); //与Assets/同级的Output/文件夹
//            if (!Directory.Exists(outputPath))
//                Directory.CreateDirectory(outputPath);

//            return outputPath;
//        }

//        public static void BuildAssetBundles()
//        {
//            // Choose the output path according to the build target.
//            var outputPath = CreateAssetBundleDirectory();
//            Debug.Log($"BuildAssetBundles: 构建Ab包生成文件夹: {outputPath}");

//            const BuildAssetBundleOptions options = BuildAssetBundleOptions.ChunkBasedCompression;
//            var rules = GetBuildRules();
//            AssetBundleBuild[] builds = null; // rules.GetAbBuilds();

//            var targetPlatform = EditorUserBuildSettings.activeBuildTarget;
//            var assetBundleManifest = BuildPipeline.BuildAssetBundles(outputPath, builds, options, targetPlatform);
//            if (assetBundleManifest == null)
//            {
//                Debug.Log("BuildPipeline.BuildAssetBundles return null");
//                return;
//            }

//            var manifest = GetManifest();
//            var bundles = assetBundleManifest.GetAllAssetBundles();

//            var bundle2Ids = new Dictionary<string, int>();
//            for (var index = 0; index < bundles.Length; index++)
//            {
//                var bundle = bundles[index];
//                bundle2Ids[bundle] = index;
//            }

//            //manifest中的所有bundle信息
//            var bundleRefs = new List<BundleRef>();
//            for (var index = 0; index < bundles.Length; index++)
//            {
//                var bundle = bundles[index];
//                var deps = assetBundleManifest.GetAllDependencies(bundle);
//                var path = string.Format("{0}/{1}", outputPath, bundle);
//                if (File.Exists(path))
//                {
//                    using (var stream = File.OpenRead(path))
//                    {
//                        bundleRefs.Add(new BundleRef
//                        {
//                            name = bundle,
//                            id = index,
//                            deps = Array.ConvertAll(deps, input => bundle2Ids[input]),
//                            len = stream.Length,
//                            hash = assetBundleManifest.GetAssetBundleHash(bundle).ToString(),
//                        });
//                    }
//                }
//                else
//                {
//                    Debug.LogError(path + " file not exsit.");
//                }
//            }

//            //有own包的资源的信息
//            var dirs = new List<string>();
//            var assets = new List<AssetRef>();
//            //不属于任何Bundle的dep资源不会出现在这边???
//            //for (var i = 0; i < rules.ruleAssets.Length; i++)
//            //{
//            //    var item = rules.ruleAssets[i];
//            //    var path = item.path; //资源路径
//            //    var dir = Path.GetDirectoryName(path).Replace('\\', '/');
//            //    /*
//            //    var index = dirs.FindIndex((o) =>
//            //    {
//            //        return o.Equals(dir);
//            //    });
//            //    */
//            //    var index = dirs.IndexOf(dir);
//            //    //列表中还没有则添加
//            //    if (index == -1)
//            //    {
//            //        //Debug.Log($"BuildAssetBundles: {dir}");
//            //        index = dirs.Count;
//            //        dirs.Add(dir);
//            //    }

//            //    var asset = new AssetRef { bundle = bundle2Ids[item.bundle], dir = index, name = Path.GetFileName(path) };
//            //    assets.Add(asset);
//            //}

//            /////manifest.searchDirs = Array.ConvertAll(rules.rules, item => item.searchPath);
//            manifest.dirs = dirs.ToArray();
//            manifest.assets = assets.ToArray();
//            manifest.bundles = bundleRefs.ToArray();

//            Debug.Log($"BuildAssetBundles: 序列化Manifest");
//            EditorUtility.SetDirty(manifest);
//            AssetDatabase.SaveAssets(); //序列化Manifest资源
//            AssetDatabase.Refresh();

//            //===资源版本号
//            var version = 0;
//            var versionFile = string.Format("{0}/{1}", outputPath, Versions.BuildVersion);
//            if (File.Exists(versionFile))
//            {
//                version = int.Parse(File.ReadAllText(versionFile));
//                version = version + 1;
//            }

//            File.WriteAllText(versionFile, version.ToString());
//            Debug.Log($"BuildAssetBundles: 生成build_version文件");


//            var manifestBundleName = "manifest.unity3d";
//            builds = new[]
//            {
//                new AssetBundleBuild
//                {
//                    assetNames = new[] {AssetDatabase.GetAssetPath(manifest),},
//                    assetBundleName = manifestBundleName
//                }
//            };

//            BuildPipeline.BuildAssetBundles(outputPath, builds, options, targetPlatform); //Manifest.asset构建为manifest.unity3d
//            Debug.Log($"BuildAssetBundles: 单独构建manifest.unity3d");
//            ArrayUtility.Add(ref bundles, manifestBundleName);
//            ArrayUtility.Add(ref bundles, Versions.BuildVersion);

//            if (Directory.Exists(rules.outputPath))
//            {
//                var files = Directory.GetFiles(rules.outputPath);
//                foreach (var file in files)
//                {
//                    File.Delete(file);
//                }
//            }
//            else
//            {
//                Directory.CreateDirectory(rules.outputPath);
//            }

//            //从Assets/Output/windows拷贝到Assets/Bundles
//            foreach (var item in bundles)
//            {
//                var sourceFileName = string.Format("{0}/{1}", outputPath, item);
//                var destFileName = string.Format("{0}/{1}", rules.outputPath, item);
//                File.Copy(sourceFileName, destFileName, true);
//            }
//            Debug.Log($"BuildAssetBundles: 拷贝: {outputPath} => {rules.outputPath}");

//            Versions.BuildVersions(rules.outputPath);
//        }



//        /// <summary>
//        /// 应用包名称
//        /// </summary>
//        private static string GetBuildTargetName(BuildTarget target)
//        {
//            var time = DateTime.Now.ToString("yyyyMMdd-HHmmss");
//            var name = PlayerSettings.productName + "-v" + PlayerSettings.bundleVersion + "-" + time;
//            switch (target)
//            {
//                case BuildTarget.Android:
//                    return "/" + name + PlayerSettings.Android.bundleVersionCode + ".apk";

//                case BuildTarget.StandaloneWindows:
//                case BuildTarget.StandaloneWindows64:
//                    return "/" + name + PlayerSettings.Android.bundleVersionCode + ".exe";

//#if UNITY_2017_3_OR_NEWER
//                case BuildTarget.StandaloneOSX:
//                    return "/" + name + ".app";

//#else
//                case BuildTarget.StandaloneOSXIntel:
//                case BuildTarget.StandaloneOSXIntel64:
//                case BuildTarget.StandaloneOSXUniversal:
//                    return "/" + name + ".app";

//#endif

//                case BuildTarget.WebGL:
//                case BuildTarget.iOS:
//                    return "";
//                // Add more build targets for your own.
//                default:
//                    Debug.Log("Target not implemented.");
//                    return null;
//            }
//        }

//        private static T GetAsset<T>(string path) where T : ScriptableObject
//        {
//            var asset = AssetDatabase.LoadAssetAtPath<T>(path);
//            if (asset == null)
//            {
//                asset = ScriptableObject.CreateInstance<T>(); //将类序列化成资源
//                AssetDatabase.CreateAsset(asset, path);
//                AssetDatabase.SaveAssets();
//            }

//            return asset;
//        }

//        public static Settings GetSettings()
//        {
//            const string path = "Assets/Settings.asset";
//            return GetAsset<Settings>(path);
//        }

//        public static Manifest GetManifest()
//        {
//            return GetAsset<Manifest>(Assets.ManifestAsset);
//        }
//    }
//}